package com.kexio.user.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.cache.annotation.CacheEvict;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
// import com.kexio.auth.spi.PermissionChangeNotifier;
// import com.kexio.auth.version.PermissionVersionService;
import com.kexio.auth.util.AuthContextUtils;
import com.kexio.common.enums.StatusEnum;
import com.kexio.common.exception.BusinessException;
import com.kexio.common.utils.ValidationUtils;
import com.kexio.user.entity.Menu;
import com.kexio.user.entity.Permission;
import com.kexio.user.entity.Role;
import com.kexio.user.entity.RolePermission;
import com.kexio.user.entity.User;
import com.kexio.user.entity.UserRole;
import com.kexio.user.mapper.MenuMapper;
import com.kexio.user.mapper.PermissionMapper;
import com.kexio.user.mapper.RoleMapper;
import com.kexio.user.mapper.RolePermissionMapper;
import com.kexio.user.mapper.UserMapper;
import com.kexio.user.mapper.UserRoleMapper;
import com.kexio.user.service.PermissionService;
import com.kexio.user.service.PermissionSyncService;
import com.kexio.user.service.UserService;

/**
 * 权限服务实现类
 * 
 * 提供权限管理的核心业务逻辑实现
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Service
public class PermissionServiceImpl implements PermissionService {
    
    private static final Logger logger = LoggerFactory.getLogger(PermissionServiceImpl.class);
    
    @Autowired
    private PermissionMapper permissionMapper;
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private UserService userService;
    
    @Autowired(required = false)
    private com.kexio.auth.cache.CacheInvalidationService cacheInvalidationService;
    
    @Autowired(required = false)
    private com.kexio.user.service.PermissionVersionService permVersionService;
    
    @Autowired(required = false)
    private PermissionSyncService permissionSyncService;
    
    // ==================== 基础CRUD操作 ====================
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Permission createPermission(Permission permission) {
        ValidationUtils.notNull(permission, "权限信息不能为空");
        
        // 统一由租户拦截器处理租户字段，不在此处做必填校验
        ValidationUtils.notBlank(permission.getCode(), "权限编码不能为空");
        ValidationUtils.notBlank(permission.getName(), "权限名称不能为空");
        
        // 检查权限编码是否已存在
        if (existsByCode(permission.getCode(), null)) {
            throw BusinessException.dataExists("权限编码已存在：" + permission.getCode());
        }
        
        // 设置默认值
        permission.setId(UUID.randomUUID().toString());
        permission.setCreateTime(LocalDateTime.now());
        permission.setUpdateTime(LocalDateTime.now());
        
        if (permission.getStatus() == null) {
            permission.setStatus(StatusEnum.ENABLED.getValue()); // 默认启用
        }
        
        if (!StringUtils.hasText(permission.getType())) {
            permission.setType("OP"); // 默认操作权限
        }
        
        // 插入数据库
        permissionMapper.insert(permission);
        
        logger.info("创建权限成功: permissionId={}, permissionCode={}, permissionName={}, tenantId={}", 
                   permission.getId(), permission.getCode(), permission.getName(), permission.getTenantId());
        
         String tenantId = AuthContextUtils.getCurrentTenantId();
         // 通知权限变更
         notifyPermissionChanged(tenantId, permission.getId(), "permission_created");
         
         // 清理相关权限缓存
         invalidatePermissionRelatedCaches(permission.getId(), tenantId, "permission_created");
         
         // ✅ 新增：权限创建后，通知相关用户版本更新（通过角色级联）
         updatePermissionRelatedUsersVersion(permission.getId(), "PERMISSION_CREATED");
        
        return permission;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Permission updatePermission(String permissionId, Permission permission) {
        ValidationUtils.notBlank(permissionId, "权限ID不能为空");
        ValidationUtils.notNull(permission, "权限信息不能为空");
        
        // 统一由租户拦截器处理租户字段，不在此处做必填校验
        
        // 查询现有权限
        Permission existingPermission = getPermissionById(permissionId);
        if (existingPermission == null) {
            throw BusinessException.resourceNotFound("权限不存在：" + permissionId);
        }
        
        // 检查权限编码是否已存在（排除当前权限）
        if (StringUtils.hasText(permission.getCode()) && !permission.getCode().equals(existingPermission.getCode())) {
            if (existsByCode(permission.getCode(), permissionId)) {
                throw BusinessException.dataExists("权限编码已存在：" + permission.getCode());
            }
        }
        
        // 更新权限信息
        LambdaUpdateWrapper<Permission> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Permission::getId, permissionId);
        updateWrapper.set(Permission::getUpdateTime, LocalDateTime.now());
        
        if (StringUtils.hasText(permission.getCode())) {
            updateWrapper.set(Permission::getCode, permission.getCode());
        }
        if (StringUtils.hasText(permission.getName())) {
            updateWrapper.set(Permission::getName, permission.getName());
        }
        if (permission.getStatus() != null) {
            updateWrapper.set(Permission::getStatus, permission.getStatus());
        }
        if (StringUtils.hasText(permission.getType())) {
            updateWrapper.set(Permission::getType, permission.getType());
        }
        if (StringUtils.hasText(permission.getDescription())) {
            updateWrapper.set(Permission::getDescription, permission.getDescription());
        }
        // 新架构：更新菜单关联ID
        if (permission.getMenuId() != null) {  // 允许设置为null以清除关联
            updateWrapper.set(Permission::getMenuId, permission.getMenuId());
        }
        
        int updated = permissionMapper.update(null, updateWrapper);
        if (updated > 0) {
            // 查询更新后的权限信息
            Permission updatedPermission = getPermissionById(permissionId);
            
            logger.info("更新权限成功: permissionId={}, permissionCode={}, permissionName={}, tenantId={}", 
                       permissionId, permission.getCode(), permission.getName(), permission.getTenantId());
            
             String tenantId = AuthContextUtils.getCurrentTenantId();
             // 通知权限变更
             notifyPermissionChanged(tenantId, permissionId, "permission_updated");
             
             // 清理相关权限缓存
             invalidatePermissionRelatedCaches(permissionId, tenantId, "permission_updated");
             
             // ✅ 新增：权限更新后，通知相关用户版本更新（通过角色级联）
             updatePermissionRelatedUsersVersion(permissionId, "PERMISSION_UPDATED");
            
            return updatedPermission;
        } else {
            throw BusinessException.operationFailed("更新权限失败，可能权限不存在或已被删除");
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePermission(String permissionId) {
        if (!StringUtils.hasText(permissionId)) {
            return false;
        }
        
        String tenantId = AuthContextUtils.getCurrentTenantId();
        
        // 检查权限是否存在
        Permission existingPermission = getPermissionById(permissionId);
        if (existingPermission == null) {
            logger.warn("要删除的权限不存在: permissionId={}, tenantId={}", permissionId, tenantId);
            return false;
        }
        
        // 检查权限是否被使用
        if (isPermissionInUse(permissionId)) {
            throw BusinessException.operationFailed("权限正在被使用，无法删除");
        }
        
        // 逻辑删除权限，使用 @TableLogic
        int deleted = permissionMapper.deleteById(permissionId);
        
        if (deleted > 0) {
            logger.info("删除权限成功: permissionId={}, permissionCode={}, tenantId={}", 
                       permissionId, existingPermission.getCode(), tenantId);
            
            // 通知权限变更
            notifyPermissionChanged(tenantId, permissionId, "permission_deleted");
            
            // 清理相关权限缓存
            invalidatePermissionRelatedCaches(permissionId, tenantId, "permission_deleted");
            
            // ✅ 新增：权限删除后，通知相关用户版本更新（通过角色级联）
            updatePermissionRelatedUsersVersion(permissionId, "PERMISSION_DELETED");
            
            return true;
        }
        
        return false;
    }
    
    @Override
    public Permission getPermissionById(String permissionId) {
        if (!StringUtils.hasText(permissionId)) {
            return null;
        }
        
        String tenantId = AuthContextUtils.getCurrentTenantId();
        try {
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Permission::getId, permissionId)
;
            
            return permissionMapper.selectOne(queryWrapper);
        } catch (Exception e) {
            logger.error("查询权限失败: permissionId={}, tenantId={}", permissionId, tenantId, e);
            return null;
        }
    }
    
    @Override
    public Permission getPermissionByCode(String permissionCode) {
        if (!StringUtils.hasText(permissionCode)) {
            return null;
        }
        
        String tenantId = AuthContextUtils.getCurrentTenantId();
        try {
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Permission::getCode, permissionCode)
;
            
            return permissionMapper.selectOne(queryWrapper);
        } catch (Exception e) {
            logger.error("根据编码查询权限失败: permissionCode={}, tenantId={}", permissionCode, tenantId, e);
            return null;
        }
    }
    
    // ==================== 权限列表查询 ====================
    
    @Override
    public Page<Permission> getPermissionPage(Long current, Long size) {
        String tenantId = AuthContextUtils.getCurrentTenantId();
        
        try {
            Page<Permission> page = new Page<>(
                com.kexio.common.page.PageUtils.normalizePageNo(current),
                com.kexio.common.page.PageUtils.normalizePageSize(size)
            );
            
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper
                        .orderByDesc(Permission::getCreateTime);
            
            return permissionMapper.selectPage(page, queryWrapper);
        } catch (Exception e) {
            logger.error("分页查询权限失败: tenantId={}, current={}, size={}", tenantId, current, size, e);
            return new Page<>();
        }
    }
    
    @Override
    public Page<Permission> getPermissionPage(Long current, Long size,
                                           String permissionCode, String permissionName, 
                                           String permissionType, Integer status, String menuId) {
        String tenantId = AuthContextUtils.getCurrentTenantId();
        try {
            Page<Permission> page = new Page<>(
                com.kexio.common.page.PageUtils.normalizePageNo(current),
                com.kexio.common.page.PageUtils.normalizePageSize(size)
            );
            
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            
            // 添加条件查询
            if (StringUtils.hasText(permissionCode)) {
                queryWrapper.like(Permission::getCode, permissionCode);
            }
            if (StringUtils.hasText(permissionName)) {
                queryWrapper.like(Permission::getName, permissionName);
            }
            if (StringUtils.hasText(permissionType)) {
                queryWrapper.eq(Permission::getType, permissionType);
            }
            if (status != null) {
                queryWrapper.eq(Permission::getStatus, status);
            }
            if (StringUtils.hasText(menuId)) {
                queryWrapper.eq(Permission::getMenuId, menuId);
            }
            
            queryWrapper.orderByDesc(Permission::getCreateTime);
            
            Page<Permission> permissionPage = permissionMapper.selectPage(page, queryWrapper);
            
            logger.debug("带条件分页查询权限成功: tenantId={}, current={}, size={}, permissionCode={}, permissionName={}, permissionType={}, status={}, menuId={}, total={}", 
                        tenantId, current, size, permissionCode, permissionName, permissionType, status, menuId, permissionPage.getTotal());
            
            return permissionPage;
            
        } catch (Exception e) {
            logger.error("带条件分页查询权限失败: tenantId={}, current={}, size={}, permissionCode={}, permissionName={}, permissionType={}, status={}, menuId={}, error={}", 
                        tenantId, current, size, permissionCode, permissionName, permissionType, status, menuId, e.getMessage(), e);
            return new Page<>();
        }
    }
    
    @Override
    public List<Permission> getPermissionsByTenant() {
        
        try {
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            
            // 租户过滤由拦截器统一处理
            
            // 只查询启用的权限
            queryWrapper.eq(Permission::getStatus, 1)
                        .orderByAsc(Permission::getOrderNo)  // 按排序号升序
                        .orderByDesc(Permission::getCreateTime);
            
            List<Permission> result = permissionMapper.selectList(queryWrapper);
            logger.debug("查询租户权限成功: tenantId={}, count={}",  result.size());
            
            return result;
        } catch (Exception e) {
            logger.error("查询租户权限失败: tenantId={}", e);
            return Collections.emptyList();
        }
    }
    
    @Override
    public List<Permission> getPermissionsByType(String permissionType) {
        if (!StringUtils.hasText(permissionType)) {
            return Collections.emptyList();
        }
        
        try {
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper
                        .eq(Permission::getType, permissionType)
                        .orderByDesc(Permission::getCreateTime);
            
            return permissionMapper.selectList(queryWrapper);
        } catch (Exception e) {
            logger.error("根据类型查询权限失败: permissionType={}, tenantId={}", permissionType,  e);
            return Collections.emptyList();
        }
    }
    
    @Override
    public List<Permission> getActivePermissions() {
        
        try {
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper
                        .eq(Permission::getStatus, 1)
                        .orderByDesc(Permission::getCreateTime);
            
            return permissionMapper.selectList(queryWrapper);
        } catch (Exception e) {
            logger.error("查询启用权限失败: tenantId={}",  e);
            return Collections.emptyList();
        }
    }
    
    // ==================== 权限树形结构 ====================
    
    @Override
    public List<Permission> getPermissionTree() {
        
        try {
            // 获取所有权限
            List<Permission> allPermissions = getPermissionsByTenant();
            
            if (allPermissions == null || allPermissions.isEmpty()) {
                logger.debug("租户无权限数据");
                return Collections.emptyList();
            }
            
            // 构建权限树
            List<Permission> rootPermissions = buildPermissionTree(allPermissions);
            
            logger.debug("权限树构建完成: tenantId={}, rootCount={}",
                        rootPermissions.size(), allPermissions.size());
            
            return rootPermissions;
            
        } catch (Exception e) {
            logger.error("构建权限树失败: , error={}",  e.getMessage(), e);
            return Collections.emptyList();
        }
    }
    
    /**
     * 构建权限树结构
     */
    private List<Permission> buildPermissionTree(List<Permission> allPermissions) {
        if (allPermissions == null || allPermissions.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 建立ID到权限的映射
        Map<String, Permission> permissionMap = allPermissions.stream()
                .collect(Collectors.toMap(Permission::getId, p -> p, (a, b) -> a));
        
        // 为每个权限初始化子权限列表
        allPermissions.forEach(permission -> {
            if (permission.getChildren() == null) {
                permission.setChildren(new ArrayList<>());
            }
        });
        
        // 构建父子关系
        List<Permission> rootPermissions = new ArrayList<>();
        
        for (Permission permission : allPermissions) {
            String parentId = permission.getParentId();
            
            if (parentId == null || "0".equals(parentId) || parentId.trim().isEmpty()) {
                // 根权限
                rootPermissions.add(permission);
            } else {
                // 子权限，找到父权限并添加到其children中
                Permission parent = permissionMap.get(parentId);
                if (parent != null) {
                    parent.getChildren().add(permission);
                } else {
                    // 如果找不到父权限，将其视为根权限
                    logger.warn("权限父节点不存在，视为根权限: permissionId={}, parentId={}", 
                              permission.getId(), parentId);
                    rootPermissions.add(permission);
                }
            }
        }
        
        // 对权限树进行排序
        sortPermissionTree(rootPermissions);
        
        return rootPermissions;
    }
    
    /**
     * 对权限树进行排序
     */
    private void sortPermissionTree(List<Permission> permissions) {
        if (permissions == null || permissions.isEmpty()) {
            return;
        }
        
        // 按照orderNo排序，如果orderNo为空则使用0
        permissions.sort((a, b) -> {
            Integer orderA = a.getOrderNo() != null ? a.getOrderNo() : 0;
            Integer orderB = b.getOrderNo() != null ? b.getOrderNo() : 0;
            int result = orderA.compareTo(orderB);
            
            // 如果orderNo相同，则按名称排序
            if (result == 0) {
                String nameA = a.getName() != null ? a.getName() : "";
                String nameB = b.getName() != null ? b.getName() : "";
                result = nameA.compareTo(nameB);
            }
            
            return result;
        });
        
        // 递归排序子权限
        for (Permission permission : permissions) {
            if (permission.getChildren() != null && !permission.getChildren().isEmpty()) {
                sortPermissionTree(permission.getChildren());
            }
        }
    }
    
    // ==================== 权限检查 ====================
    
    @Override
    public boolean hasPermission(String userId, String permissionCode) {
        if (!StringUtils.hasText(userId) || !StringUtils.hasText(permissionCode)) {
            return false;
        }
        try {
            List<String> codes = userService.getUserPermissions(userId);
            return codes != null && codes.contains(permissionCode);
        } catch (Exception e) {
            logger.error("检查用户单权限失败: userId={}, permissionCode={}, tenantId={}", userId, permissionCode, e);
            return false;
        }
    }
    
    @Override
    public boolean hasAnyPermission(String userId, List<String> permissionCodes) {
        if (!StringUtils.hasText(userId) || permissionCodes == null || permissionCodes.isEmpty()) {
            return false;
        }
        try {
            List<String> codes = userService.getUserPermissions(userId);
            if (codes == null || codes.isEmpty()) return false;
            for (String pc : permissionCodes) {
                if (codes.contains(pc)) return true;
            }
            return false;
        } catch (Exception e) {
            logger.error("检查用户任一权限失败: userId={}", userId, e);
            return false;
        }
    }
    
    @Override
    public boolean hasAllPermissions(String userId, List<String> permissionCodes) {
        if (!StringUtils.hasText(userId) || permissionCodes == null || permissionCodes.isEmpty()) {
            return false;
        }
        try {
            List<String> codes = userService.getUserPermissions(userId);
            if (codes == null || codes.isEmpty()) return false;
            for (String pc : permissionCodes) {
                if (!codes.contains(pc)) return false;
            }
            return true;
        } catch (Exception e) {
            logger.error("检查用户全部权限失败: userId={}", userId, e);
            return false;
        }
    }
    
    @Override
    public boolean roleHasPermission(String roleId, String permissionCode) {
        if (!StringUtils.hasText(roleId) || !StringUtils.hasText(permissionCode)) {
            return false;
        }
        try {
            // 通过角色-权限表检查
            if (rolePermissionMapper == null) return false;
            Long count = rolePermissionMapper.selectCount(new LambdaQueryWrapper<RolePermission>()
                .eq(RolePermission::getRoleId, roleId)
                .last("AND EXISTS (SELECT 1 FROM sys_permission p WHERE p.code = '" + permissionCode + "' AND p.id = sys_role_permission.permission_id)")
            );
            return count != null && count > 0L;
        } catch (Exception e) {
            logger.error("检查角色权限失败: roleId={}, permissionCode={}", roleId, permissionCode, e);
            return false;
        }
    }
    
    // ==================== 权限继承处理 ====================
    
    @Override
    public List<Permission> getEffectivePermissions(String permissionId) {
        // 当前无继承模型，返回本体
        if (!StringUtils.hasText(permissionId)) {
            return Collections.emptyList();
        }
        try {
            Permission p = getPermissionById(permissionId);
            return p != null ? java.util.Collections.singletonList(p) : java.util.Collections.emptyList();
        } catch (Exception e) {
            logger.error("获取有效权限失败: permissionId={}", permissionId,  e);
            return Collections.emptyList();
        }
    }
    
    @Override
    public boolean isPermissionInherited(String childPermissionId, String parentPermissionId) {
        // 未实现权限继承模型，固定为 false
        return false;
    }
    
    // ==================== 统计查询 ====================
    
    @Override
    public Long countPermissionsByTenant() {
        try {
            return permissionMapper.selectCount(new LambdaQueryWrapper<Permission>());
        } catch (Exception e) {
            String tenantId = AuthContextUtils.getCurrentTenantId();
            logger.error("统计租户权限数量失败: tenantId={}", tenantId, e);
            return 0L;
        }
    }
    
    @Override
    public Long countActivePermissions() {
        try {
            return permissionMapper.selectCount(new LambdaQueryWrapper<Permission>()
                .eq(Permission::getStatus, StatusEnum.ENABLED.getValue()));
        } catch (Exception e) {
            logger.error("统计启用权限数量失败", e);
            return 0L;
        }
    }
    
    @Override
    public Map<String, Long> countPermissionsByType() {
        try {
            java.util.Map<String, Long> result = new java.util.HashMap<>();
            // 简化：统计 OP 与 MENU 两类（如有字段）
            Long op = permissionMapper.selectCount(new LambdaQueryWrapper<Permission>()
                .eq(Permission::getType, "OP"));
            Long menu = permissionMapper.selectCount(new LambdaQueryWrapper<Permission>()
                .eq(Permission::getType, "MENU"));
            result.put("OP", op);
            result.put("MENU", menu);
            return result;
        } catch (Exception e) {
            logger.error("统计权限类型数量失败", e);
            return java.util.Collections.emptyMap();
        }
    }
    
    @Override
    public Long countPermissionRoles(String permissionId) {
        if (!StringUtils.hasText(permissionId)) return 0L;
        try {
            if (rolePermissionMapper == null) return 0L;
            return rolePermissionMapper.selectCount(new LambdaQueryWrapper<RolePermission>()
                .eq(RolePermission::getPermissionId, permissionId)
);
        } catch (Exception e) {
            logger.error("统计权限关联角色数量失败: permissionId={}", permissionId, e);
            return 0L;
        }
    }
    
    // ==================== 数据验证 ====================
    
    @Override
    public boolean existsByCode(String permissionCode, String excludePermissionId) {
        if (!StringUtils.hasText(permissionCode)) {
            return false;
        }

        try {
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Permission::getCode, permissionCode)
;

            if (StringUtils.hasText(excludePermissionId)) {
                queryWrapper.ne(Permission::getId, excludePermissionId);
            }

            return permissionMapper.selectCount(queryWrapper) > 0;
        } catch (Exception e) {
            logger.error("检查权限编码是否存在失败: permissionCode={}", permissionCode, e);
            return false;
        }
    }
    
    @Override
    public boolean existsByName(String permissionName, String excludePermissionId) {
        if (!StringUtils.hasText(permissionName)) {
            return false;
        }

        try {
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Permission::getName, permissionName);

            if (StringUtils.hasText(excludePermissionId)) {
                queryWrapper.ne(Permission::getId, excludePermissionId);
            }

            return permissionMapper.selectCount(queryWrapper) > 0;
        } catch (Exception e) {
            logger.error("检查权限名称是否存在失败: permissionName={}", permissionName, e);
            return false;
        }
    }
    
    @Override
    public boolean isPermissionInUse(String permissionId) {
        if (!StringUtils.hasText(permissionId)) {
            return false;
        }

        String tenantId = AuthContextUtils.getCurrentTenantId();
        try {
            // 真正实现：检查是否有角色关联此权限
            if (rolePermissionMapper != null) {
                logger.debug("检查权限是否被使用: permissionId={}", permissionId);
                
                // 使用LambdaQueryWrapper查询角色权限关联
                Long count = rolePermissionMapper.selectCount(
                    new LambdaQueryWrapper<RolePermission>()
                        .eq(RolePermission::getPermissionId, permissionId)
                );
                if (count > 0) {
                    logger.info("权限被角色关联，不能删除: permissionId={}, roleCount={}", permissionId, count);
                    return true;
                }
            }
            
            // 在新架构下，权限直接通过menu_id关联菜单，无需额外检查
            return false;
        } catch (Exception e) {
            logger.error("检查权限是否被使用失败: permissionId={}, tenantId={}", permissionId, tenantId, e);
            return false;
        }
    }
    
    @Override
    public boolean isResourcePathUnique(String resourcePath, String excludePermissionId) {
        if (!StringUtils.hasText(resourcePath)) return true;
        try {
            Long count = permissionMapper.selectCount(new LambdaQueryWrapper<Permission>()
                .eq(Permission::getPath, resourcePath)
                .ne(StringUtils.hasText(excludePermissionId), Permission::getId, excludePermissionId));
            return count == null || count == 0L;
        } catch (Exception e) {
            logger.error("检查资源路径唯一性失败:  path={}", resourcePath, e);
            return true;
        }
    }
    
    // ==================== 缓存管理 ====================
    
    
    /**
     * 清理权限相关的缓存
     * 
     * @param permissionId 权限ID（可为null表示全局刷新）
     * @param tenantId 租户ID
     * @param reason 缓存刷新原因
     */
    private void invalidatePermissionRelatedCaches(String permissionId, String tenantId, String reason) {
        if (!StringUtils.hasText(tenantId)) {
            logger.warn("租户ID为空，跳过权限相关缓存清理");
            return;
        }
        
        // ✅ 使用统一缓存服务清理权限相关缓存
        try {
            if (cacheInvalidationService != null) {
                cacheInvalidationService.clearAllPermissionRelatedCaches(tenantId);
                logger.info("权限相关缓存清理完成 (统一服务): permissionId={}, tenantId={}, reason={}", 
                           permissionId, tenantId, reason);
            } else {
                logger.warn("缓存清理服务未配置，跳过权限缓存清理: permissionId={}, tenantId={}", 
                           permissionId, tenantId);
            }
        } catch (Exception e) {
            logger.error("清理权限相关缓存失败: permissionId={}, tenantId={}, reason={}", 
                        permissionId, tenantId, reason, e);
        }
        /*
        try {
            if (cacheInvalidationService != null) {
                // 1. 如果权限与菜单相关联，清理菜单缓存
                if (StringUtils.hasText(permissionId)) {
                    Permission permission = getPermissionById(permissionId);
                    if (permission != null && StringUtils.hasText(permission.getMenuId())) {
                        cacheInvalidationService.clearMenuCaches(permission.getMenuId(), tenantId);
                    }
                }
                
                // 2. 清理租户下所有用户的权限缓存（权限变更会影响所有相关用户）
                // 注意：这个操作可能比较重，大租户需要考虑异步处理
                // 这里简化处理，直接清理租户级缓存
                logger.info("开始清理权限相关缓存: permissionId={}, tenantId={}, reason={}", 
                           permissionId, tenantId, reason);
                
                // 暂时使用租户级清理，后续可以优化为更精确的清理策略
                cacheInvalidationService.clearTenantCaches(tenantId);
                
                logger.info("权限相关缓存清理完成: permissionId={}, tenantId={}, reason={}", 
                           permissionId, tenantId, reason);
            }
        } catch (Exception e) {
            // 缓存清理失败不应该影响业务流程
            logger.error("清理权限相关缓存失败: permissionId={}, tenantId={}, reason={}", 
                        permissionId, tenantId, reason, e);
        }
        */
    }
    
    @Override
    public void refreshUserPermissionCache(String userId) {
        String tenantId = AuthContextUtils.getCurrentTenantId();
        
        logger.info("用户权限缓存刷新 (JWT架构下已简化): userId={}, tenantId={}", userId, tenantId);
    }
    
    
    @Override
    public void refreshPermissionCache() {
        String tenantId = AuthContextUtils.getCurrentTenantId();
        try {
            // ✅ 使用统一缓存服务清理权限相关缓存
            if (cacheInvalidationService != null) {
                cacheInvalidationService.clearAllPermissionRelatedCaches(tenantId);
            }
            
            // 1. 通过权限变更通知器清理缓存（保留Sa-Token通知机制）
            notifyPermissionChanged(tenantId, null, "TENANT_PERMISSION_CACHE_REFRESH");
            
            // 3. 如果有权限投影写入器，重建租户下所有用户的权限投影
            // if (permissionProjectionWriter != null && userService != null) {
            if (false && userService != null) {  // 禁用此分支
                try {
                    // 获取租户下所有活跃用户（谨慎：大租户可能有性能影响）
                    // 这里简化实现，在实际场景中可能需要分批处理
                    logger.info("开始重建租户权限投影: tenantId={}", tenantId);
                    // 可以通过事件机制异步处理，避免阻塞主流程
                } catch (Exception e) {
                    logger.warn("重建租户权限投影失败: tenantId={}, error={}", tenantId, e.getMessage());
                }
            }
            
            logger.info("权限缓存刷新完成 (Spring Cache + Sa-Token): tenantId={}", tenantId);
        } catch (Exception e) {
            logger.error("权限缓存刷新失败: tenantId={}, error={}", tenantId, e.getMessage(), e);
        }
    }
    
    @Override
    public void notifyPermissionChange(String permissionId, String operatorId) {
        String tenantId = AuthContextUtils.getCurrentTenantId();
        // 触发与该权限相关的用户投影重建（通过角色关联反查用户）
        logger.info("权限变更通知 (JWT架构下已简化): permissionId={}, operatorId={}, tenantId={}", 
                   permissionId, operatorId, tenantId);
        
    }
    
    // ==================== 权限状态管理 ====================
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePermissionStatus(String permissionId, Integer status) {
        if (!StringUtils.hasText(permissionId)) {
            throw new IllegalArgumentException("权限ID不能为空");
        }
        if (status == null) {
            throw new IllegalArgumentException("状态不能为空");
        }
        
        String tenantId = AuthContextUtils.getCurrentTenantId();
        try {
            // 检查权限是否存在
            Permission existingPermission = getPermissionById(permissionId);
            if (existingPermission == null) {
                throw BusinessException.resourceNotFound("权限不存在");
            }
            
            // 更新权限状态
            LambdaUpdateWrapper<Permission> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Permission::getId, permissionId)
                        .set(Permission::getStatus, status)
                        .set(Permission::getUpdateTime, LocalDateTime.now());
            
            boolean result = permissionMapper.update(null, updateWrapper) > 0;
            
            if (result) {
                logger.info("权限状态更新成功: permissionId={}, status={}, tenantId={}", permissionId, status, tenantId);
                
                // 通知权限变更
                notifyPermissionChange(permissionId, "PERMISSION_STATUS_UPDATED");
                
                return true;
            } else {
                throw BusinessException.operationFailed("更新权限状态失败");
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            logger.error("更新权限状态异常: permissionId={}, status={}, tenantId={}, error={}", 
                        permissionId, status, tenantId, e.getMessage(), e);
            throw BusinessException.operationFailed("更新权限状态失败: " + e.getMessage());
        }
    }
    
    // ==================== 权限关联查询 ====================
    
    
    @Override
    public List<Role> getPermissionRoles(String permissionId) {
        if (!StringUtils.hasText(permissionId)) {
            return Collections.emptyList();
        }
        
        try {
            // 通过角色权限关联表找到拥有该权限的角色
            LambdaQueryWrapper<RolePermission> rolePermissionQuery = new LambdaQueryWrapper<>();
            rolePermissionQuery.eq(RolePermission::getPermissionId, permissionId)
                              .select(RolePermission::getRoleId);
            List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionQuery);
            
            if (rolePermissions.isEmpty()) {
                return Collections.emptyList();
            }
            
            // 获取角色ID列表
            List<String> roleIds = rolePermissions.stream()
                    .map(RolePermission::getRoleId)
                    .distinct()
                    .collect(Collectors.toList());
            
            // 查询角色详细信息
            LambdaQueryWrapper<Role> roleQuery = new LambdaQueryWrapper<>();
            roleQuery.in(Role::getId, roleIds)
                    .eq(Role::getStatus, StatusEnum.ENABLED.getValue())
                    .orderByAsc(Role::getOrderNo, Role::getName);
            
            List<Role> roles = roleMapper.selectList(roleQuery);
            
            logger.debug("查询权限关联的角色成功: permissionId={}, roleCount={}", permissionId, roles.size());
            
            return roles;
        } catch (Exception e) {
            logger.error("查询权限关联的角色失败: permissionId={}, error={}", permissionId, e.getMessage(), e);
            return Collections.emptyList();
        }
    }
    
    @Override
    public List<User> getPermissionUsers(String permissionId) {
        if (!StringUtils.hasText(permissionId)) {
            return Collections.emptyList();
        }
        
        try {
            // 通过角色权限关联表找到拥有该权限的角色
            LambdaQueryWrapper<RolePermission> rolePermissionQuery = new LambdaQueryWrapper<>();
            rolePermissionQuery.eq(RolePermission::getPermissionId, permissionId)
                              .select(RolePermission::getRoleId);
            List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionQuery);
            
            if (rolePermissions.isEmpty()) {
                return Collections.emptyList();
            }
            
            // 获取角色ID列表
            List<String> roleIds = rolePermissions.stream()
                    .map(RolePermission::getRoleId)
                    .distinct()
                    .collect(Collectors.toList());
            
            // 通过用户角色关联表找到拥有这些角色的用户
            LambdaQueryWrapper<UserRole> userRoleQuery = new LambdaQueryWrapper<>();
            userRoleQuery.in(UserRole::getRoleId, roleIds)
                        .select(UserRole::getUserId);
            List<UserRole> userRoles = userRoleMapper.selectList(userRoleQuery);
            
            if (userRoles.isEmpty()) {
                return Collections.emptyList();
            }
            
            // 获取用户ID列表
            List<String> userIds = userRoles.stream()
                    .map(UserRole::getUserId)
                    .distinct()
                    .collect(Collectors.toList());
            
            // 查询用户信息
            LambdaQueryWrapper<User> userQuery = new LambdaQueryWrapper<>();
            userQuery.in(User::getId, userIds)
                    .eq(User::getDeleted, 0)
                    .orderByAsc(User::getCreateTime);
            List<User> users = userMapper.selectList(userQuery);
            
            logger.debug("获取权限关联用户成功: permissionId={}, userCount={}", permissionId, users.size());
            return users;
            
        } catch (Exception e) {
            logger.error("获取权限关联用户失败: permissionId={}, error={}", permissionId, e.getMessage(), e);
            return Collections.emptyList();
        }
    }
    
    @Override
    public List<Permission> getPermissionsByMenuId(String menuId) {
        if (!StringUtils.hasText(menuId)) {
            logger.warn("根据菜单ID查询权限参数无效: menuId={}", menuId);
            return Collections.emptyList();
        }
        
        try {
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Permission::getMenuId, menuId)
                       .eq(Permission::getStatus, 1)
                       .orderByAsc(Permission::getOrderNo);
            
            List<Permission> permissions = permissionMapper.selectList(queryWrapper);
            logger.debug("根据菜单ID查询权限成功: menuId={}, count={}", 
                        menuId, permissions.size());
            return permissions;
            
        } catch (Exception e) {
            logger.error("根据菜单ID查询权限失败: menuId={}, error={}", 
                        menuId, e.getMessage(), e);
            return Collections.emptyList();
        }
    }
    
    @Override
    public Map<String, List<Permission>> getMenuPermissionMap() {
        try {
            // 查询所有有菜单关联的权限
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.isNotNull(Permission::getMenuId)
                       .eq(Permission::getStatus, 1)
                       .orderByAsc(Permission::getOrderNo);
            
            List<Permission> permissions = permissionMapper.selectList(queryWrapper);
            
            // 按菜单ID分组
            Map<String, List<Permission>> menuPermissionMap = permissions.stream()
                    .collect(Collectors.groupingBy(Permission::getMenuId));
            
            logger.debug("获取菜单权限映射成功: menuCount={}, totalPermissions={}", 
                        menuPermissionMap.size(), permissions.size());
            return menuPermissionMap;
            
        } catch (Exception e) {
            logger.error("获取菜单权限映射失败: error={}", e.getMessage(), e);
            return Collections.emptyMap();
        }
    }
    
    // ==================== 私有辅助方法 ====================
    
    /**
     * 通知权限变更
     * 
     * @param tenantId 租户ID
     * @param permissionId 权限ID
     * @param reason 变更原因
     */
    private void notifyPermissionChanged(String tenantId, String permissionId, String reason) {
        // ✅ 精简JWT架构：权限变更需要同步Redis和JWT版本
        logger.info("🔄 权限变更通知 (精简JWT架构): permissionId={}, tenantId={}, reason={}", 
                   permissionId, tenantId, reason);
        
        // Sa-Token架构下权限变更自动生效，无需手动同步
        logger.debug("Sa-Token架构下权限变更自动生效，无需手动同步");
    }
    
    /**
     * 更新权限相关用户的版本号
     * 
     * 权限变更后，需要更新所有拥有该权限的用户的 permVersion
     * 流程：权限 → 角色 → 用户
     * 
     * @param permissionId 权限ID
     * @param reason 变更原因
     */
    private void updatePermissionRelatedUsersVersion(String permissionId, String reason) {
        if (permVersionService == null) {
            logger.debug("PermissionVersionService 未注入，跳过权限相关用户版本更新");
            return;
        }
        
        if (!StringUtils.hasText(permissionId)) {
            logger.warn("权限ID为空，跳过权限相关用户版本更新");
            return;
        }
        
        try {
            // 1. 查询拥有该权限的所有角色
            LambdaQueryWrapper<RolePermission> query = new LambdaQueryWrapper<>();
            query.eq(RolePermission::getPermissionId, permissionId)
                 .select(RolePermission::getRoleId);
            
            List<RolePermission> rolePermissions = rolePermissionMapper.selectList(query);
            
            if (rolePermissions == null || rolePermissions.isEmpty()) {
                logger.debug("权限未分配给任何角色，无需更新用户版本: permissionId={}", permissionId);
                return;
            }
            
            // 2. 提取角色ID列表（去重）
            List<String> roleIds = rolePermissions.stream()
                .map(RolePermission::getRoleId)
                .filter(StringUtils::hasText)
                .distinct()
                .collect(Collectors.toList());
            
            logger.debug("权限关联的角色: permissionId={}, roleCount={}", permissionId, roleIds.size());
            
            // 3. 批量更新每个角色下的所有用户
            int totalAffectedUsers = 0;
            for (String roleId : roleIds) {
                try {
                    int affectedUsers = permVersionService.onRolePermissionChanged(roleId);
                    totalAffectedUsers += affectedUsers;
                } catch (Exception e) {
                    logger.warn("⚠️ 更新角色用户权限版本失败: roleId={}, error={}", roleId, e.getMessage());
                }
            }
            
            logger.info("✅ 权限变更，批量更新用户权限版本: permissionId={}, roleCount={}, totalAffectedUsers={}, reason={}", 
                permissionId, roleIds.size(), totalAffectedUsers, reason);
                
        } catch (Exception e) {
            logger.error("❌ 权限相关用户版本更新失败: permissionId={}, reason={}, error={}", 
                permissionId, reason, e.getMessage(), e);
        }
    }
    
    @Override
    public Long countPermissionsByPattern(String pattern) {
        if (!StringUtils.hasText(pattern)) {
            return 0L;
        }
        
        try {
            // 将通配符模式转换为SQL LIKE模式
            String likePattern = pattern.replace("*", "%").replace("?", "_");
            
            // 使用QueryWrapper进行模糊查询
            LambdaQueryWrapper<Permission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.like(Permission::getCode, likePattern);
            
            return permissionMapper.selectCount(queryWrapper);
        } catch (Exception e) {
            logger.error("根据模式统计权限数量失败: pattern={}, error={}", pattern, e.getMessage());
            return 0L;
        }
    }
}
